package com.lnu.information.aop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lnu.information.dao.AppUserMapper;
import com.lnu.information.dto.BaseResponseDTO;
import com.lnu.information.entity.AppUserEntity;
import com.lnu.information.entity.company_listedcompany_detailinforEntity;
import com.lnu.information.exception.QueryException;
import com.lnu.information.service.CompanyService;
import com.lnu.information.util.CheckUtils;
import com.lnu.information.util.ClassUtil;
import com.lnu.information.util.ValidateUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.MessageFormat;

/**
 * @author : jian.zhang-2
 * @description:
 * @date : Create in 3:40 PM 2022/3/10
 * @modified By :
 */
@Component
@Aspect
public class TryCatchAspect {
    /***
     * 设置日志
     */
    private static final Logger logger = LoggerFactory.getLogger(TryCatchAspect.class);

    @Resource
    private AppUserMapper appUserMapper;


    //            "|| execution (* com.yeepay.g3.core.remit.facade.impl.RemitFacadeImpl.*(..))" +
//            "|| execution (* com.yeepay.g3.core.trade.yop.facade.impl..*.*(..))")
    @Pointcut("execution (* com.lnu.information.controller..*.*(..)) ")
    private void aopMethod() {

    }

    @Around("TryCatchAspect.aopMethod()")
    public Object serviceAOP(ProceedingJoinPoint pjp) throws Throwable{
        try {
            JSONObject jsonObject = null;
            Object[] param = pjp.getArgs();
            if(param.length == 2){
                jsonObject = JSON.parseObject(param[1].toString());
            }else {
                jsonObject = JSON.parseObject(param[0].toString());
            }
            Object appKey = jsonObject.get("appKey");
            if(CheckUtils.isEmpty(appKey)){
                throw new QueryException(QueryException.QueryExceptionEnum.ILLEGAL_PARAM_EXCEPTION).newInstance("appKey不能为空");
            }
            ValidateUtil.checkRequestParam(appKey.toString(), "appKey");
            QueryWrapper<AppUserEntity> queryWrapper = new QueryWrapper<>();
            //参数为表中的列名，要查询的条件 相当于 WHERE name = name
            queryWrapper.eq("user_id", appKey.toString());
            AppUserEntity appUserEntity = appUserMapper.selectOne(queryWrapper);
            if(appUserEntity == null){
                throw new QueryException(QueryException.QueryExceptionEnum.WRONG_APPKEY_EXCEPTION);
            }
            Signature signature = pjp.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            logger.info("查询接口方法名{}, 请求参数：{}", methodSignature.getMethod(), JSON.toJSONString(param));
            Object result = pjp.proceed();
            logger.info("查询接口方法名{}, 响应参数：{}", methodSignature.getMethod(),JSON.toJSONString(result));
            return result;
        }catch(Throwable t){
            //异常处理
            Signature signature = pjp.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            Object baseResponseDTO = methodSignature.getReturnType().newInstance();
            logger.error(MessageFormat.format("查询接口方法名{0}, 异常信息：{1}，堆栈信息：", methodSignature.getMethod(),t), t);
            BaseResponseDTO realBaseResponseDTO = (BaseResponseDTO)baseResponseDTO;
            if(t instanceof QueryException) {
                QueryException re = (QueryException) t;
                realBaseResponseDTO.setCode(re.getDefineCode());
                realBaseResponseDTO.setMsg(re.getMessage());
            }else {
                Exception re = (Exception) t;
                realBaseResponseDTO.setCode(QueryException.QueryExceptionEnum.SYSTEM_EXCEPTION.getCode());
                realBaseResponseDTO.setMsg(re.getMessage());
            }

            return baseResponseDTO;
        }
    }
}
